﻿using mozhi.smarterp.Finance.Enums;
using mozhi.smarterp.Finance.Files.Services;
using mozhi.smarterp.Finance.Logs;
using mozhi.smarterp.Finance.Logs.Repository;
using Mozhi.Abp.Core.Offices.Excels;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace mozhi.smarterp.Finance.Ieps.Export
{
    public class ExportHandlerBase<TData> : IExportHandler where TData : class
    {
        protected List<TData> _datas;

        protected ExcelDocument _excelDocument;

        protected IOperationLogAppService _operationLogAppService;

        protected ExportQueryDto _query;

        protected IOperationLogRepository _operationLogRepository;

        protected FileManager _fileManager;

        protected IServiceProvider _serviceProvider;

        public ExportHandlerBase(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;

            _operationLogAppService = _serviceProvider.GetService(typeof(IOperationLogAppService)) as IOperationLogAppService;
            _operationLogRepository = _serviceProvider.GetService(typeof(IOperationLogRepository)) as IOperationLogRepository;
            _fileManager = _serviceProvider.GetService(typeof(FileManager)) as FileManager;
        }


        public async Task<mozhi.smarterp.Finance.Files.File> GetExportStreamAsync(ExportQueryDto query)
        {
            if (query.ModuleCode.IsNullOrEmpty())
                throw new ArgumentNullException(nameof(query.ModuleCode));

            _query = query;

            //获取数据
            _datas = await GetDatasAsync();

            //获取ExcelDocument对象
            _excelDocument = await GetExcelDocumentAsync();

            //在生成excel文件流

            var stream = await GetExcelFileStreamAsync();

            //文件名
            var fileName = GetFileName();


            //写入日志
            await WriteExportLogAsync();

            //上传文件
            var file = await UploadFileAsync(fileName , stream);

            return file;
        }

        protected virtual async Task<List<TData>> GetDatasAsync()
        {
            return default(List<TData>);
        }

        protected virtual async Task<ExcelDocument> GetExcelDocumentAsync()
        {
            return default(ExcelDocument);
        }


        protected virtual async Task<Stream> GetExcelFileStreamAsync()
        {
            var excelHandler = ExcelHandlerFactory.Instance("npio");

            var stream = excelHandler.GetExcelFileStream(_excelDocument);

            return stream;
        }

        protected virtual string GetFileName()
        {
            string fileName = GetModuleName();

            return $"{fileName}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx";
        }


        protected virtual string GetModuleName()
        {
            string name = "";

            if (_query.ModuleCode == ModuleCodeType.Supplier)
                name = "供应商";
            else if (_query.ModuleCode == ModuleCodeType.Customer)
                name = "客户";
            else if (_query.ModuleCode == ModuleCodeType.Thirdparty)
                name = "第三方";
            else if (_query.ModuleCode == ModuleCodeType.Account)
                name = "科目";

            return name;
        }


        protected virtual async Task WriteExportLogAsync()
        {
            var operationLog = new OperationLog(Guid.NewGuid(), null, "导出", Enums.OperationType.Export, "Export", "导出", default, GetModuleName(), "");

            await _operationLogRepository.InsertAsync(operationLog);

        }

        protected virtual async Task<mozhi.smarterp.Finance.Files.File> UploadFileAsync(string fileName, Stream stream)
        {
            var file = await _fileManager.CreateAsync(fileName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", stream);

            return file;
        }
    }
}
